package client_gui_chat;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.ListSelectionModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import utils.Constants;

/**
 * Klasa predstavlja FontDialog - dialog za izbor fonta.
 * @author UrosKrkic & Radivoje Popovic
 */
public class FontDialog extends JDialog implements Constants, ActionListener, ChangeListener, ListSelectionListener {

	private static final long serialVersionUID = -72406497317995021L;
	
	final int pointSizeMin = 8;
	final int pointSizeMax = 36;
	final int pointSizeStep = 2;
	
	private JSpinner chooseSize;	// Font size options
	private JLabel fontDisplay;		// Font sample

	private JList fontList;			// Font list
  
	private JButton ok;				// OK button
	private JButton cancel;			// Cancel button
	
	private JButton fontColorButton;

	private Font font;				// Currently selected font
	private int fontStyle;			// Font style - Plain,Bold,Italic
	private int fontSize;			// Font point size
	private Color fontColor = Color.BLACK;
	
	private ChatDialog parent;
	
	public FontDialog(ChatDialog window) {
		// Call the base constructor to create a modal dialog
		super(window, "Font Selection", true);
		
		this.parent = window;
		
		font = new Font(parent.getClientUser().getFontName(), parent.getClientUser().getFontStyle(), parent.getClientUser().getFontSize());
		fontStyle = font.getStyle();
		fontSize = font.getSize();
		fontColor = parent.getClientUser().getFontColor();

		// Create the dialog button panel 
		JPanel buttonPane = new JPanel();

		// Create and add the buttons to the buttonPane
		buttonPane.add(ok = createButton("OK"));
		buttonPane.add(cancel = createButton("Cancel"));
		getContentPane().add(buttonPane, BorderLayout.SOUTH);

		// Code to create the data input panel
		JPanel dataPane = new JPanel(); 
		dataPane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createLineBorder(Color.BLACK),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));  
		
		GridBagLayout gbLayout = new GridBagLayout();
		dataPane.setLayout(gbLayout);
		GridBagConstraints constraints = new GridBagConstraints();

		// Code to create the font choice and add it to the input panel
		JLabel label = new JLabel("Choose a Font");
		constraints.fill = GridBagConstraints.HORIZONTAL;
		constraints.gridwidth = GridBagConstraints.REMAINDER; 
		gbLayout.setConstraints(label, constraints);
		dataPane.add(label);

		// Code to set up font list choice component
		GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
		String[] fontNames = e.getAvailableFontFamilyNames();

		fontList = new JList(fontNames);
		fontList.setValueIsAdjusting(true);
		fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		fontList.setSelectedValue(font.getFamily(), true);
		fontList.addListSelectionListener(this);
		
		JScrollPane chooseFont = new JScrollPane(fontList);
		chooseFont.setMinimumSize(new Dimension(300,100));
		chooseFont.setWheelScrollingEnabled(true);

		// Panel to display font sample
		JPanel display = new JPanel();
		fontDisplay = new JLabel("Sample Size: x X y Y z Z");
		fontDisplay.setFont(font);
		fontDisplay.setPreferredSize(new Dimension(300,100));
		fontDisplay.setForeground(fontColor);
		display.add(fontDisplay);

		// Create a split pane with font choice at the top
		// and font display at the bottom
		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
									true,
									chooseFont,
									display);
		gbLayout.setConstraints(splitPane, constraints);
		dataPane.add(splitPane);

		// Set up the size choice using a spinner
		JPanel sizePane = new JPanel();
		label = new JLabel("Choose point size");
		sizePane.add(label);
 
		chooseSize = new JSpinner(new SpinnerNumberModel(fontSize,
									pointSizeMin, pointSizeMax, pointSizeStep));
		chooseSize.addChangeListener(this);
		
		sizePane.add(chooseSize);

		// Add spinner to pane
		gbLayout.setConstraints(sizePane, constraints);
		dataPane.add(sizePane);

		
		// Set up style options using radio buttons
		JRadioButton bold = new JRadioButton("Bold", (fontStyle & Font.BOLD) > 0);
		JRadioButton italic = new JRadioButton("Italic", (fontStyle & Font.ITALIC) > 0);

		bold.addItemListener(new StyleListener(Font.BOLD));
		italic.addItemListener(new StyleListener(Font.ITALIC));

		fontColorButton = new JButton("Color");
		fontColorButton.setMargin(new Insets(0,0,0,0));
		fontColorButton.setPreferredSize(new Dimension(50,25));
		fontColorButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				fontColor = JColorChooser.showDialog(FontDialog.this, "Select Custom Color", fontColor);
				fontDisplay.setForeground(fontColor);
				fontDisplay.repaint();
			}
		});
		
		JPanel stylePane = new JPanel();
		FlowLayout fl = new FlowLayout();
		fl.setHgap(20);
		stylePane.setLayout(fl);
		stylePane.add(bold);
		stylePane.add(italic);
		stylePane.add(fontColorButton);
		gbLayout.setConstraints(stylePane, constraints);
		dataPane.add(stylePane);

		getContentPane().add(dataPane, BorderLayout.CENTER);
		pack();
		
		this.setLocation(parent.getX() + parent.getWidth() / 2 - this.getWidth() / 2, parent.getY() + parent.getHeight() / 2 - this.getHeight() / 2);
		
		setVisible(false);
	}

	
	public void stateChanged(ChangeEvent e) {
//		fontSize = ((Number)(((JSpinner)e.getSource()).getValue())).intValue();
		fontSize = Integer.parseInt(chooseSize.getValue().toString());
		font = font.deriveFont((float)fontSize);
		fontDisplay.setFont(font);
		fontDisplay.repaint();    
	}

	// List selection listener method
	public void valueChanged(ListSelectionEvent e) {
		if( !e.getValueIsAdjusting() ) {
			font = new Font((String)fontList.getSelectedValue(), fontStyle, fontSize);
			fontDisplay.setFont(font);
			fontDisplay.repaint();
		}
	}

	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();						// Get the source of the event
		if (source == ok)  {								// Is it the OK button?
			parent.getClientUser().setFontName(font.getName());
			parent.getClientUser().setFontStyle(font.getStyle());
			parent.getClientUser().setFontSize(font.getSize());
			parent.getClientUser().setFontColor(fontColor);
			
			parent.setPanelsFont(font);
			
			setVisible(false);								// Hide the dialog
		}
		else if (source == cancel)							// If it is the Cancel button
			setVisible(false);								// just hide the dialog
	}

	
	private JButton createButton(String label) {
		JButton button = new JButton(label);				// Create the button
		button.setPreferredSize(new Dimension(80,20));		// Set the size
		button.addActionListener(this);						// Listener is the dialog

		return button;										// Return the button
	}

	
	
	
	private class StyleListener implements ItemListener {
		
		private int style;							// Style for this listener
		
		public StyleListener(int style) {  
			this.style = style;  
		}

		public void itemStateChanged(ItemEvent e) {
			if (e.getStateChange() == ItemEvent.SELECTED)	// If style was selected
				fontStyle |= style;							// turn it on in the font style
			else
				fontStyle &= ~style;						// otherwise turn it off
			
			font = font.deriveFont(fontStyle);				// Get a new font
			fontDisplay.setFont(font);						// Change the label font
			fontDisplay.repaint();							// repaint
		}    
	}
	
}
